package com.server.db.jedis;

import java.util.ArrayList;
import com.server.db.bean.Ltlx;
import com.sandking.config.SK_Config;
import java.util.Map;
import com.sandking.tools.SK_Plus;
import java.util.List;
import com.sandking.tools.SK_String;
import java.util.Collections;
import com.sandking.tools.SK_List;
import java.util.Comparator;
import com.server.db.DbLock;
import com.sandking.constant.SK_ErrorCode;
import com.sandking.tools.SK_PageCount;
import java.util.concurrent.locks.ReentrantLock;
import com.sandking.tools.SK_Exception;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Jedis;
/**
 * 聊天类型
 * 1.做为Jedis单独使用的情况，我是不建议的!他不能保证线程安全性问题，没有数据补救的操作
 * 2.jedis的查询数据是没有顺序的
 */
public class LtlxJedis{
	static class LtlxSore implements Comparator<Ltlx> {
		@Override
		public int compare(Ltlx ltlx1, Ltlx ltlx2) {
			if (ltlx1.getId() > ltlx2.getId())
				return 1;
			else if (ltlx1.getId() < ltlx2.getId())
				return -1;
			else {
				return 0;
			}
		}
	}
	//表锁(重入锁)
	static final ReentrantLock tableLock = new ReentrantLock();
	
	static Comparator<Ltlx> comparator = new LtlxSore();
	
	/**
	 * 根据( id ) 查询
	 */
	public static Ltlx getById(int id){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Ltlx ltlx = null;
		try{
			String key = "Ltlx_Object";
			String field = SK_Plus.b("id:",id).e();
			String json = jedis.hget(key,field);
			if(!SK_String.isEmpty(json))
				ltlx = Ltlx.createForJson(json);
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return ltlx;
	}
	
	public static List<Ltlx> getByIdIn(int[] ids){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Ltlx> ltlxs = new ArrayList<Ltlx>();
		try{
			String key = "Ltlx_Object";
			String[] strIds = new String[ids.length];
			for (int i = 0; i < strIds.length; i++) {
				strIds[i] = String.valueOf(ids[i]);
			}
			List<String> jsons = jedis.hmget(key,strIds);
			 ltlxs = Ltlx.createForJson(jsons);
		}catch (Exception e) {
			
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return ltlxs;
	}

	public static List<Ltlx> getAll(){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Ltlx> ltlxs = new ArrayList<Ltlx>();
		try{
			String key = "Ltlx_Object";
			List<String> jsons = jedis.hvals(key);
			ltlxs = Ltlx.createForJson(jsons);
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		Collections.sort(ltlxs, comparator);
		return ltlxs;
	}
	
	
	public static List<Ltlx> getAllByPage(int page,int size,SK_PageCount pageCount){
		List<Ltlx> ltlxs = getAll();
		ltlxs = SK_List.getPage(ltlxs, page, size, pageCount);
		return ltlxs;
	}
	
	
	public static Ltlx putData(Ltlx ltlx,Pipeline p,int type) throws SK_Exception{
		boolean isLock = (type == SK_Config.CHECK_ALL_INDEX);
		Map<String,String> updateIndexs = null;
		if(type == SK_Config.CHECK_UPDATE_INDEX){
			updateIndexs = ltlx.getUpdateIndexs();
			isLock = updateIndexs.containsKey("isUpdtaeUnique");
		}
		try{
			DbLock.lock(ltlx.getId(),DbLock.ltlx_locks);
			if(isLock)tableLock.lock();
			switch (type) {
			case SK_Config.CHECK_ALL_INDEX:
				checkUniqueIndex(ltlx);
				break;
			case SK_Config.CHECK_UPDATE_INDEX:
				checkUniqueIndex(updateIndexs);
				break;
			}
			if(type == SK_Config.CHECK_UPDATE_INDEX){
				removeData(ltlx);
			}
			// ---------------------- 主键索引 ----------------------
			String key = "Ltlx_Object";
			String field = SK_Plus.b("id:",ltlx.getId()).e();
			String data = ltlx.toJson();
			p.hset(key,field,data);
			
		}finally{
			 DbLock.unlock(ltlx.getId(),DbLock.ltlx_locks);
			 if(isLock)tableLock.unlock();
		}
		return ltlx;
	}
	
	public static List<Ltlx> putDataAll(List<Ltlx> ltlxs,int type){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		List<Ltlx> ltlxs_ = new ArrayList<Ltlx>();
		try{
			Pipeline p = jedis.pipelined();
			for(Ltlx ltlx : ltlxs){
				try {
					ltlxs_.add(putData(ltlx,p,type));
				} catch (SK_Exception e) {
					e.printStackTrace();
				}
			}
			p.sync();
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
		return ltlxs_;
	}
	
	public static void removeData(Ltlx ltlx){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			Pipeline p = jedis.pipelined();
			removeData(ltlx,p);
			p.sync();
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
	}
	
	/**
	 * 清空一个缓存
	 */
	public static void removeData(Ltlx ltlx,Pipeline p){
		try{
			DbLock.lock(ltlx.getId(),DbLock.ltlx_locks);
			// ---------------------- 主键索引 ----------------------
			String key = "Ltlx_Object";
			String field = SK_Plus.b("id:",ltlx.getId_Unique()).e();
			p.hdel(key,field);
			
		}finally{
			 DbLock.unlock(ltlx.getId(),DbLock.ltlx_locks);
		}
	}

	public static void removeDataAll(List<Ltlx> ltlxs){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			Pipeline p = jedis.pipelined();
			for(Ltlx ltlx : ltlxs){
				removeData(ltlx,p);
			}
			p.sync();
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
	}
	
	public static Ltlx insert(Ltlx ltlx){
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		Jedis jedisPipeline = SK_Config.getJedisPoll().getResource();
		Pipeline p = jedisPipeline.pipelined();
		try{
			if(ltlx.getId() < 1){
				try {
					tableLock.lock();
					ltlx.setId(jedis.hincrBy("primaryKey", Ltlx.CLASS_NAME,1).intValue());
				}finally{
					tableLock.unlock();
				}
			}
			DbLock.lock(ltlx.getId(),DbLock.ltlx_locks);
			try {
				ltlx = putData(ltlx, p, SK_Config.CHECK_ALL_INDEX);
				p.sync();
				return ltlx;
			} catch (SK_Exception e) {
				e.printStackTrace();
			}
    	}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
			 SK_Config.getJedisPoll().returnResource(jedisPipeline);
			 DbLock.unlock(ltlx.getId(),DbLock.ltlx_locks);
		}
		return null;
    }
    
    public static List<Ltlx> insertBatch(List<Ltlx> ltlxs){
    	Jedis jedis = SK_Config.getJedisPoll().getResource();
    	try{
			ltlxs = putDataAll(ltlxs, SK_Config.CHECK_ALL_INDEX);
			jedis.hincrBy("primaryKey", Ltlx.CLASS_NAME,ltlxs.size());
		}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
		}
    	return ltlxs;
    }
    
    public static Ltlx update(Ltlx ltlx){
    	Jedis jedis = SK_Config.getJedisPoll().getResource();
		Jedis jedisPipeline = SK_Config.getJedisPoll().getResource();
		Pipeline p = jedisPipeline.pipelined();
		try{
			DbLock.lock(ltlx.getId(),DbLock.ltlx_locks);
			try{
				ltlx = putData(ltlx,p,SK_Config.CHECK_UPDATE_INDEX);
				p.sync();
				return ltlx;
			} catch (SK_Exception e) {
				e.printStackTrace();
			}
    	}finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
			 SK_Config.getJedisPoll().returnResource(jedisPipeline);
			 DbLock.unlock(ltlx.getId(),DbLock.ltlx_locks);
		}
		return null;
    }
    
    public static List<Ltlx> updateBatch(List<Ltlx> ltlxs){
    	removeDataAll(ltlxs);
		putDataAll(ltlxs,SK_Config.CHECK_UPDATE_INDEX);
    	return ltlxs;
    }
    
    public static boolean delete(Ltlx ltlx){
    	Jedis jedis = SK_Config.getJedisPoll().getResource();
		Jedis jedisPipeline = SK_Config.getJedisPoll().getResource();
		Pipeline p = jedisPipeline.pipelined();
		boolean bool = true;
		try{
			DbLock.lock(ltlx.getId(),DbLock.ltlx_locks);
	    	removeData(ltlx,p);
	    	p.sync();
	    }finally{
			 SK_Config.getJedisPoll().returnResource(jedis);
			 SK_Config.getJedisPoll().returnResource(jedisPipeline);
			 DbLock.unlock(ltlx.getId(),DbLock.ltlx_locks);
		}
	    return bool;
    }
    
    public static boolean deleteBatch(List<Ltlx> ltlxs){
    	boolean bool = true;
    	removeDataAll(ltlxs);
    	return bool;
    }
    
    
    
    //检查唯一索引
	private static void checkUniqueIndex(Ltlx ltlx) throws SK_Exception{
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			tableLock.lock();
			String key = "Ltlx_Object";
			String field = SK_Plus.b("id:",SK_Plus.b(ltlx.getId()).e()).e();
			if(jedis.hexists(key,field))
				throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Ltlx.Id_IndexName,"=",field).e());
				
		}finally{
			SK_Config.getJedisPoll().returnResource(jedis);
			tableLock.unlock();
		}
	}
	
	/** 检查(改变的)唯一索引 */
	private static void checkUniqueIndex(Map<String,String> indexs) throws SK_Exception{
		Jedis jedis = SK_Config.getJedisPoll().getResource();
		try{
			tableLock.lock();
			String key = "";
			for (Map.Entry<String, String> index : indexs.entrySet()) {
				switch (index.getKey()) {
				case Ltlx.Id_IndexName:
					key = "Ltlx_Object";
					if(jedis.hexists(key,SK_Plus.b("id:",index.getValue()).e()))
						throw new SK_Exception(SK_ErrorCode.UNIQUE_INDEX_ERROR,SK_Plus.b(Ltlx.Id_IndexName,"=",index.getValue()).e());
					break;
				}
			}
		}finally{
			SK_Config.getJedisPoll().returnResource(jedis);
			tableLock.unlock();
		}
	}
}